<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<script>
    /*
        (1)类型：
            Map的键可以是任何类型的值，包括基本类型（如字符串或数字）和对象引用。
            而WeakMap的键只能是对象类型。这是因为WeakMap的设计初衷是存储对象及其对应的值，
            并且其键对对象的引用是弱的，不会阻止GC回收键所引用的对象。
        (2)引用关系：
            Map中的键值对是强引用关系，只要Map对象存在，其中的键值对就不会被自动回收。
            相反，WeakMap中的键值对是弱引用关系。如果WeakMap中使用的某个键对象没有被其他地方引用，
            那么在垃圾回收时，这个键对象及其对应的值都会被自动回收。
        (3)可枚举性与大小：
            Map支持对键和值进行迭代，可以使用size属性获取键值对的数量，也可以使用clear方法清空Map。
            然而，WeakMap不支持对键和值进行迭代，也没有size属性和clear方法，无法获取WeakMap的所有键或值。
    

        使用场景：
        WeakMap：
            在开发中我们可能需要将某些数据与DOM元素关联起来。
            使用WeakMap，我们可以将DOM元素作为键，相关的数据作为值。
            这样，当DOM元素被从DOM树中移除时，由于WeakMap的弱引用特性，
            与该元素关联的数据也会自动被垃圾回收，无需手动清理，从而避免了内存泄漏。
    */
    let weakMap = new WeakMap();
    let map = new Map();
    (function() {
        let obj = { name: 'test object' };
        let obj2 = { name: 'test object' };
        weakMap.set(obj, 'data');
        const mapv = map.set(obj2, 'data');
        console.log('迭代', mapv.keys())
        mapv.forEach(key => {
            console.log(key)
        })
    })();
    // 模拟内存压力，强迫垃圾回收
    let memoryPressure = [];
    for (let i = 0; i < 1000000; i++) {
        memoryPressure.push({}); // 填充内存
    }
    // 由于没有手动触发垃圾回收，测试时可以在这里加延时
    setTimeout(() => {
        console.log(map);  // obj 应该已经被垃圾回收
        console.log(weakMap);  // obj 应该已经被垃圾回收
    }, 1000);
</script>

<body>

</body>
</html>